AWS CDK で ALB の接続ログ(Connection logs)が設定可能になっていました

AWS CDK で ALB の接続ログ(Connection logs)が設定可能になっていました

Clock Icon2024.08.27

こんにちは、製造ビジネステクノロジー部の若槻です。

AWS CDK の最近のリリースで、下記のアップデートが追加されていました。

https://github.com/aws/aws-cdk/releases/tag/v2.154.0

elasticloadbalancingv2: connection logs for ALB (#30599) (7c4f423)

Application Load Balancer(ALB) の接続ログ(Connection logs)は、昨年 11 月にサポートされた ALB のロードバランサーに送信されたリクエストに関する詳細情報を取得できる機能です。

https://dev.classmethod.jp/articles/alb-connection-logs/

今回の CDK のアップデートは ALB の L2 Construct 実装である aws_elasticloadbalancingv2 でその接続ログが設定可能になったというものとなります。

試してみた

CDK モジュールのアップデート

AWS CDK モジュールを v2.154.0 以上にアップデートします。

npm i aws-cdk-lib@latest aws-cdk@latest

CDK コード

CDK で ALB の接続ログを有効化してみます。elbv2.ApplicationLoadBalancer クラスに対して logConnectionLogs メソッドを呼び出すことで、ALB の接続ログを S3 に保存する設定が可能となっています。

lib/cdk-sample-stack.ts
import {
  aws_ec2 as ec2,
  aws_elasticloadbalancingv2 as elbv2,
  aws_s3 as s3,
  Stack,
  StackProps,
} from 'aws-cdk-lib';
import { Construct } from 'constructs';

export class CdkSampleStack extends Stack {
  constructor(scope: Construct, id: string, props: StackProps) {
    super(scope, id, props);

    /**
     * Virtual Private Cloud の作成
     */
    const vpc = new ec2.Vpc(this, 'VPC', {
      ipAddresses: ec2.IpAddresses.cidr('10.10.0.0/16'),
      subnetConfiguration: [
        {
          cidrMask: 24,
          name: 'Public',
          subnetType: ec2.SubnetType.PUBLIC,
        },
        {
          cidrMask: 24,
          name: 'Private',
          subnetType: ec2.SubnetType.PRIVATE_ISOLATED,
        },
      ],
    });

    /**
     * Application Load Balancer の作成
     */
    const alb = new elbv2.ApplicationLoadBalancer(this, 'ALB', {
      vpc,
      internetFacing: true,
    });

    /**
     * リスナーの作成
     */
    alb.addListener('Listener', {
      port: 80,
      defaultAction: elbv2.ListenerAction.fixedResponse(200, {
        contentType: 'text/plain',
        messageBody: 'Hello, CDK!',
      }),
    });

    /**
     * ALB の接続ログを S3 に保存
     */
    const bucket = new s3.Bucket(this, 'ALBConnectionLogsBucket');
    alb.logConnectionLogs(bucket);
  }
}

上記 CDK コードで下記のコード差分があった場合の CDK の差分を確認してみます。

$ git diff
diff --git a/lib/cdk-sample-stack.ts b/lib/cdk-sample-stack.ts
index 4cae95e..01e0ecb 100644
--- a/lib/cdk-sample-stack.ts
+++ b/lib/cdk-sample-stack.ts
@@ -48,5 +48,11 @@ export class CdkSampleStack extends Stack {
         messageBody: 'Hello, CDK!',
       }),
     });
+
+    /**
+     * ALB の接続ログを S3 に保存
+     */
+    const bucket = new s3.Bucket(this, 'ALBConnectionLogsBucket');
+    alb.logConnectionLogs(bucket);
   }
 }

CDK Diff コマンドによると、ALB で接続ログが有効化され、S3 バケットが ALB からのログの PUT を受け付けるようにバケットポリシーが更新されていることが確認できます。

$ npx cdk diff
Stack CdkSampleStack
Hold on while we create a read-only change set to get a diff with accurate replacement information (use --no-change-set to use a less accurate but faster template-only diff)
IAM Statement Changes
┌───┬───────────────────────────────────────────────────┬────────┬─────────────────┬───────────────────────────────────────────────────┬───────────────────────────────────────────────────┐
│   │ Resource                                          │ Effect │ Action          │ Principal                                         │ Condition                                         │
├───┼───────────────────────────────────────────────────┼────────┼─────────────────┼───────────────────────────────────────────────────┼───────────────────────────────────────────────────┤
│ + │ ${ALBConnectionLogsBucket.Arn}                    │ Allow  │ s3:GetBucketAcl │ Service:delivery.logs.amazonaws.com               │                                                   │
├───┼───────────────────────────────────────────────────┼────────┼─────────────────┼───────────────────────────────────────────────────┼───────────────────────────────────────────────────┤
│ + │ ${ALBConnectionLogsBucket.Arn}/AWSLogs/3005610389 │ Allow  │ s3:PutObject    │ AWS:arn:aws:iam::582318560864:root                │                                                   │
│   │ 00/*                                              │        │                 │                                                   │                                                   │
│ + │ ${ALBConnectionLogsBucket.Arn}/AWSLogs/3005610389 │ Allow  │ s3:PutObject    │ Service:delivery.logs.amazonaws.com               │ "StringEquals": {                                 │
│   │ 00/*                                              │        │                 │                                                   │   "s3:x-amz-acl": "bucket-owner-full-control"     │
│   │                                                   │        │                 │                                                   │ }                                                 │
└───┴───────────────────────────────────────────────────┴────────┴─────────────────┴───────────────────────────────────────────────────┴───────────────────────────────────────────────────┘
(NOTE: There may be security-related changes not in this list. See https://github.com/aws/aws-cdk/issues/1299)

Resources
[+] AWS::S3::Bucket ALBConnectionLogsBucket ALBConnectionLogsBucket36E47B67
[+] AWS::S3::BucketPolicy ALBConnectionLogsBucket/Policy ALBConnectionLogsBucketPolicyF5D2B1DC
[~] AWS::ElasticLoadBalancingV2::LoadBalancer ALB ALBAEE750D2
 ├─ [~] LoadBalancerAttributes
 │   └─ @@ -2,5 +2,19 @@
 │      [ ]   {[ ]     "Key": "deletion_protection.enabled",
 │      [ ]     "Value": "false"[+]   },
 │      [+]   {[+]     "Key": "connection_logs.s3.enabled",
 │      [+]     "Value": "true"[+]   },
 │      [+]   {[+]     "Key": "connection_logs.s3.bucket",
 │      [+]     "Value": {[+]       "Ref": "ALBConnectionLogsBucket36E47B67"[+]     }[+]   },
 │      [+]   {[+]     "Key": "connection_logs.s3.prefix",
 │      [+]     "Value": ""[ ]   }[ ] ]
 └─ [~] DependsOn
     └─ @@ -1,4 +1,5 @@
        [ ] [
        [+]   "ALBConnectionLogsBucketPolicyF5D2B1DC",
        [ ]   "VPCPublicSubnet1DefaultRoute91CEF279",
        [ ]   "VPCPublicSubnet1RouteTableAssociation0B0896DC",
        [ ]   "VPCPublicSubnet2DefaultRouteB7481BBA",

✨  Number of stacks with differences: 1

CDK デプロイを行って設定を実際に反映させます。

マネジメントコンソールから ALB の Attributes の設定を確認すると、接続ログが有効化されていることが確認できます。

そして、S3 バケットの中にはすでにファイルが 1 つ作成されていました。

設定時に権限などのチェックを行うためのテストファイルのようですね。

Enable ConnectionLog for ELB: app/CdkSam-ALBAE-2sQWpzSB1TTn/412f6706744d1117 at 2024-08-26T14:24:58.701Z

動作確認

実際に ALB にリクエストを送信してみます。すると、S3 バケットにログファイルが作成されました。

ログのプレフィックスの形式は下記のようになります。

bucket[/prefix]/AWSLogs/aws-account-id/elasticloadbalancing/region/yyyy/mm/dd/conn_log.aws-account-id_elasticloadbalancing_region_app.load-balancer-id_end-time_ip-address_random-string.log.gz

ログファイルをダウンロードして開くと、接続ログが記録されていることが確認できます。

2024-08-26T14:29:02.802175Z XXX.XXX.XXX.XXX 45409 80 - - - "-" - - - TID_9346dcf962eb444c890843cbd6107564
2024-08-26T14:29:02.807628Z XXX.XXX.XXX.XXX 45464 80 - - - "-" - - - TID_c3b6343980264d4ca0992bf59c138a14
2024-08-26T14:29:05.615644Z XXX.XXX.XXX.XXX 45120 80 - - - "-" - - - TID_e997cd0b7a40fb41add9e7b6447f2721
2024-08-26T14:29:05.617905Z XXX.XXX.XXX.XXX 45329 80 - - - "-" - - - TID_e43d56592c2b2a4c8bddaa388a088c77

参考までに接続ログの形式は下記のようになります。

[timestamp] [client_ip] [client_port] [listener_port] [tls_protocol] [tls_cipher] [tls_handshake_latency] [leaf_client_cert_subject] [leaf_client_cert_validity] [leaf_client_cert_serial_number] [tls_verify_status]

おわりに

AWS CDK で ALB の接続ログ(Connection logs)が設定可能になっていたのでご紹介しました。

接続ログを有効化しておくことにより、ALB へのリクエストで問題が発生した場合のトラブルシュートに役立ちます。必要に応じて有効化をご検討ください。

参考

https://docs.aws.amazon.com/ja_jp/elasticloadbalancing/latest/application/load-balancer-connection-logs.html

以上

この記事をシェアする

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.